home *** CD-ROM | disk | FTP | other *** search
/ STraTOS 1997 April & May / STraTOS 1 - 1997 April & May.iso / CD01 / INTERNET / SITES / LITTLE / P3SRC.ZIP / ATARI / FRACTAL.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-04-25  |  20.2 KB  |  1,016 lines

  1. /*****************************************************************************
  2. *                fractal.c
  3. *
  4. *  This module implements the fractal sets primitive.
  5. *
  6. *  This file was written by Pascal Massimino.
  7. *
  8. *  from Persistence of Vision(tm) Ray Tracer
  9. *  Copyright 1996 Persistence of Vision Team
  10. *---------------------------------------------------------------------------
  11. *  NOTICE: This source code file is provided so that users may experiment
  12. *  with enhancements to POV-Ray and to port the software to platforms other
  13. *  than those supported by the POV-Ray Team.  There are strict rules under
  14. *  which you are permitted to use this file.  The rules are in the file
  15. *  named POVLEGAL.DOC which should be distributed with this file. If
  16. *  POVLEGAL.DOC is not available or for more info please contact the POV-Ray
  17. *  Team Coordinator by leaving a message in CompuServe's Graphics Developer's
  18. *  Forum.  The latest version of POV-Ray may be found there as well.
  19. *
  20. * This program is based on the popular DKB raytracer version 2.12.
  21. * DKBTrace was originally written by David K. Buck.
  22. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  23. *
  24. *****************************************************************************/
  25.  
  26. #include "frame.h"
  27. #include "povray.h"
  28. #include "vector.h"
  29. #include "povproto.h"
  30. #include "bbox.h"
  31. #include "matrices.h"
  32. #include "objects.h"
  33. #include "spheres.h"
  34. #include "fractal.h"
  35. #include "quatern.h"
  36. #include "hcmplx.h"
  37.  
  38.  
  39.  
  40. /*****************************************************************************
  41. * Local preprocessor defines
  42. ******************************************************************************/
  43.  
  44. #ifndef Fractal_Tolerance
  45. #define Fractal_Tolerance 1e-7
  46. #endif
  47.  
  48.  
  49.  
  50. /*****************************************************************************
  51. * Local typedefs
  52. ******************************************************************************/
  53.  
  54.  
  55.  
  56. /*****************************************************************************
  57. * Static functions
  58. ******************************************************************************/
  59.  
  60. static int All_Fractal_Intersections PARAMS((OBJECT * Object, RAY * Ray, ISTACK * Depth_Stack));
  61. static int Inside_Fractal PARAMS((VECTOR IPoint, OBJECT * Object));
  62. static void Fractal_Normal PARAMS((VECTOR Result, OBJECT * Object, INTERSECTION * Intersect));
  63. static void *Copy_Fractal PARAMS((OBJECT * Object));
  64. static void Translate_Fractal PARAMS((OBJECT * Object, VECTOR Vector, TRANSFORM *Trans));
  65. static void Rotate_Fractal PARAMS((OBJECT * Object, VECTOR Vector, TRANSFORM *Trans));
  66. static void Scale_Fractal PARAMS((OBJECT * Object, VECTOR Vector, TRANSFORM *Trans));
  67. static void Transform_Fractal PARAMS((OBJECT * Object, TRANSFORM * Trans));
  68. static void Invert_Fractal PARAMS((OBJECT * Object));
  69. static void Destroy_Fractal PARAMS((OBJECT * Object));
  70. static void Compute_Fractal_BBox PARAMS((FRACTAL * Fractal));
  71.  
  72. /*****************************************************************************
  73. * Local variables
  74. ******************************************************************************/
  75.  
  76. static METHODS Fractal_Methods =
  77. {
  78.   All_Fractal_Intersections,
  79.   Inside_Fractal, Fractal_Normal,
  80.   Copy_Fractal,
  81.   Translate_Fractal, Rotate_Fractal,
  82.   Scale_Fractal, Transform_Fractal, Invert_Fractal,
  83.   Destroy_Fractal
  84. };
  85.  
  86. static int Allocated_Iteration_Stack_Length = 0;
  87.  
  88. DBL *Sx = NULL, *Sy = NULL, *Sz = NULL, *Sw = NULL;
  89. DBL Precision;
  90. VECTOR Direction;
  91.  
  92. static COMPLEX_FUNCTION_METHOD Complex_Function_List[] = 
  93. {
  94.   /* must match STYPE list in fractal.h */
  95.   Complex_Exp,
  96.   Complex_Log,
  97.   Complex_Sin,
  98.   Complex_ASin,
  99.   Complex_Cos,
  100.   Complex_ACos,
  101.   Complex_Tan,
  102.   Complex_ATan,
  103.   Complex_Sinh,
  104.   Complex_ASinh,
  105.   Complex_Cosh,
  106.   Complex_ACosh,
  107.   Complex_Tanh,
  108.   Complex_ATanh,
  109.   Complex_Pwr 
  110. };
  111.  
  112. /*****************************************************************************
  113. *
  114. * FUNCTION
  115. *
  116. * INPUT
  117. *
  118. * OUTPUT
  119. *
  120. * RETURNS
  121. *
  122. * AUTHOR
  123. *
  124. *   Pascal Massimino
  125. *
  126. * DESCRIPTION
  127. *
  128. *   -
  129. *
  130. * CHANGES
  131. *
  132. *   Dec 1994 : Creation.
  133. *
  134. ******************************************************************************/
  135.  
  136. static int All_Fractal_Intersections(Object, Ray, Depth_Stack)
  137. OBJECT *Object;
  138. RAY *Ray;
  139. ISTACK *Depth_Stack;
  140. {
  141.   int Intersection_Found;
  142.   int Last = 0;
  143.   int CURRENT, NEXT;
  144.   DBL Depth, Depth_Max;
  145.   DBL Dist, Dist_Next, Len;
  146.  
  147.   VECTOR IPoint, Mid_Point, Next_Point, Real_Pt;
  148.   VECTOR Real_Normal, F_Normal;
  149.   RAY New_Ray;
  150.   FRACTAL *Fractal = (FRACTAL *) Object;
  151.  
  152.   Increase_Counter(stats[Ray_Fractal_Tests]);
  153.  
  154.   Intersection_Found = FALSE;
  155.   Precision = Fractal->Precision;
  156.  
  157.   /* Get into Fractal's world. */
  158.  
  159.   if (Fractal->Trans != NULL)
  160.   {
  161.     MInvTransDirection(Direction, Ray->Direction, Fractal->Trans);
  162.     VDot(Len, Direction, Direction);
  163.  
  164.     if (Len == 0.0)
  165.     {
  166.       return (FALSE);
  167.     }
  168.  
  169.     if (Len != 1.0)
  170.     {
  171.       Len = 1.0 / sqrt(Len);
  172.       VScaleEq(Direction, Len);
  173.     }
  174.  
  175.     Assign_Vector(New_Ray.Direction, Direction);
  176.     MInvTransPoint(New_Ray.Initial, Ray->Initial, Fractal->Trans);
  177.   }
  178.   else
  179.   {
  180.     Assign_Vector(Direction, Ray->Direction);
  181.     New_Ray = *Ray;
  182.     Len = 1.0;
  183.   }
  184.  
  185.   /* Bound fractal. */
  186.  
  187.   if (!F_Bound(&New_Ray, Fractal, &Depth, &Depth_Max))
  188.   {
  189.     return (FALSE);
  190.   }
  191.  
  192.   if (Depth_Max < Fractal_Tolerance)
  193.   {
  194.     return (FALSE);
  195.   }
  196.  
  197.   if (Depth < Fractal_Tolerance)
  198.   {
  199.     Depth = Fractal_Tolerance;
  200.   }
  201.  
  202.   /* Jump to starting point */
  203.  
  204.   VScale(Next_Point, Direction, Depth);
  205.   VAddEq(Next_Point, New_Ray.Initial);
  206.  
  207.   CURRENT = D_Iteration(Next_Point, Fractal, &Dist);
  208.  
  209.   /* Light ray starting inside ? */
  210.  
  211.   if (CURRENT)
  212.   {
  213.     VAddScaledEq(Next_Point, 2.0 * Fractal_Tolerance, Direction);
  214.  
  215.     Depth += 2.0 * Fractal_Tolerance;
  216.  
  217.     if (Depth > Depth_Max)
  218.     {
  219.       return (FALSE);
  220.     }
  221.  
  222.     CURRENT = D_Iteration(Next_Point, Fractal, &Dist);
  223.   }
  224.  
  225.   /* Ok. Trace it */
  226.  
  227.   while (Depth < Depth_Max)
  228.   {
  229.     /*
  230.      * Get close to the root: Advance with Next_Point, keeping track of last
  231.      * position in IPoint...
  232.      */
  233.  
  234.     while (1)
  235.     {
  236.       if (Dist < Precision)
  237.       {
  238.         Dist = Precision;
  239.       }
  240.  
  241.       Depth += Dist;
  242.  
  243.       if (Depth > Depth_Max)
  244.       {
  245.         if (Intersection_Found)
  246.         {
  247.           Increase_Counter(stats[Ray_Fractal_Tests_Succeeded]);
  248.         }
  249.  
  250.         return (Intersection_Found);
  251.       }
  252.  
  253.       Assign_Vector(IPoint, Next_Point);
  254.       VAddScaledEq(Next_Point, Dist, Direction);
  255.  
  256.       NEXT = D_Iteration(Next_Point, Fractal, &Dist_Next);
  257.  
  258.       if (NEXT != CURRENT)
  259.       {
  260.         /* Set surface was crossed... */
  261.  
  262.         Depth -= Dist;
  263.         break;
  264.       }
  265.       else
  266.       {
  267.         Dist = Dist_Next; /* not reached */
  268.       }
  269.     }
  270.  
  271.     /* then, polish the root via bisection method... */
  272.  
  273.     while (Dist > Fractal_Tolerance)
  274.     {
  275.       Dist *= 0.5;
  276.       VAddScaled(Mid_Point, IPoint, Dist, Direction);
  277.  
  278.       Last = Iteration(Mid_Point, Fractal);
  279.  
  280.       if (Last == CURRENT)
  281.       {
  282.         Assign_Vector(IPoint, Mid_Point);
  283.  
  284.         Depth += Dist;
  285.  
  286.         if (Depth > Depth_Max)
  287.         {
  288.           if (Intersection_Found)
  289.           {
  290.             Increase_Counter(stats[Ray_Fractal_Tests_Succeeded]);
  291.           }
  292.  
  293.           return (Intersection_Found);
  294.         }
  295.       }
  296.     }
  297.  
  298.     if (CURRENT == FALSE) /* Mid_Point isn't inside the set */
  299.     {
  300.       VAddScaledEq(IPoint, Dist, Direction);
  301.  
  302.       Depth += Dist;
  303.  
  304.       Iteration(IPoint, Fractal);
  305.     }
  306.     else
  307.     {
  308.       if (Last != CURRENT)
  309.       {
  310.         Iteration(IPoint, Fractal);
  311.       }
  312.     }
  313.  
  314.     if (Fractal->Trans != NULL)
  315.     {
  316.       MTransPoint(Real_Pt, IPoint, Fractal->Trans);
  317.       Normal_Calc(Fractal, F_Normal);
  318.       MTransNormal(Real_Normal, F_Normal, Fractal->Trans);
  319.     }
  320.     else
  321.     {
  322.       Assign_Vector(Real_Pt, IPoint);
  323.       Normal_Calc(Fractal, Real_Normal);
  324.     }
  325.  
  326.     if (Point_In_Clip(Real_Pt, Object->Clip))
  327.     {
  328.       VNormalize(Real_Normal, Real_Normal);
  329.       push_normal_entry(Depth * Len, Real_Pt, Real_Normal, Object, Depth_Stack);
  330.       Intersection_Found = TRUE;
  331.  
  332.       /* If fractal isn't used with CSG we can exit now. */
  333.  
  334.       if (!(Fractal->Type & IS_CHILD_OBJECT))
  335.       {
  336.         break;
  337.       }
  338.     }
  339.  
  340.     /* Start over where work was left */
  341.  
  342.     Assign_Vector(IPoint, Next_Point);
  343.     Dist = Dist_Next;
  344.     CURRENT = NEXT;
  345.  
  346.   }
  347.  
  348.   if (Intersection_Found)
  349.   {
  350.     Increase_Counter(stats[Ray_Fractal_Tests_Succeeded]);
  351.   }
  352.   return (Intersection_Found);
  353. }
  354.  
  355. /*****************************************************************************
  356. *
  357. * FUNCTION
  358. *
  359. * INPUT
  360. *   
  361. * OUTPUT
  362. *
  363. * RETURNS
  364. *
  365. * AUTHOR
  366. *
  367. *   Pascal Massimino
  368. *
  369. * DESCRIPTION
  370. *
  371. *   -
  372. *
  373. * CHANGES
  374. *
  375. *   Dec 1994 : Creation.
  376. *
  377. ******************************************************************************/
  378.  
  379. static int Inside_Fractal(IPoint, Object)
  380. VECTOR IPoint;
  381. OBJECT *Object;
  382. {
  383.   FRACTAL *Fractal = (FRACTAL *) Object;
  384.   int Result;
  385.   static VECTOR New_Point;
  386.  
  387.   if (Fractal->Trans != NULL)
  388.   {
  389.     MInvTransPoint(New_Point, IPoint, Fractal->Trans);
  390.  
  391.     Result = Iteration(New_Point, Fractal);
  392.   }
  393.   else
  394.   {
  395.     Result = Iteration(IPoint, Fractal);
  396.   }
  397.  
  398.   if (Fractal->Inverted)
  399.   {
  400.     return (!Result);
  401.   }
  402.   else
  403.   {
  404.     return (Result);
  405.   }
  406. }
  407.  
  408. /*****************************************************************************
  409. *
  410. * FUNCTION
  411. *
  412. * INPUT
  413. *   
  414. * OUTPUT
  415. *   
  416. * RETURNS
  417. *   
  418. * AUTHOR
  419. *
  420. *   Pascal Massimino
  421. *   
  422. * DESCRIPTION
  423. *
  424. *   -
  425. *
  426. * CHANGES
  427. *
  428. *   Dec 1994 : Creation.
  429. *
  430. ******************************************************************************/
  431.  
  432. static void Fractal_Normal(Result, Object, Intersect)
  433. OBJECT *Object;
  434. VECTOR Result;
  435. INTERSECTION *Intersect;
  436. {
  437.   Assign_Vector(Result, Intersect->INormal);
  438. }
  439.  
  440. /*****************************************************************************
  441. *
  442. * FUNCTION
  443. *
  444. * INPUT
  445. *   
  446. * OUTPUT
  447. *   
  448. * RETURNS
  449. *   
  450. * AUTHOR
  451. *
  452. *   Pascal Massimino
  453. *   
  454. * DESCRIPTION
  455. *
  456. *   -
  457. *
  458. * CHANGES
  459. *
  460. *   Dec 1994 : Creation.
  461. *
  462. ******************************************************************************/
  463.  
  464. static void Translate_Fractal(Object, Vector, Trans)
  465. OBJECT *Object;
  466. VECTOR Vector;
  467. TRANSFORM *Trans;
  468. {
  469.   Transform_Fractal(Object, Trans);
  470. }
  471.  
  472. /*****************************************************************************
  473. *
  474. * FUNCTION
  475. *
  476. * INPUT
  477. *   
  478. * OUTPUT
  479. *   
  480. * RETURNS
  481. *   
  482. * AUTHOR
  483. *
  484. *   Pascal Massimino
  485. *   
  486. * DESCRIPTION
  487. *
  488. *   -
  489. *
  490. * CHANGES
  491. *
  492. *   Dec 1994 : Creation.
  493. *
  494. ******************************************************************************/
  495.  
  496. static void Rotate_Fractal(Object, Vector, Trans)
  497. OBJECT *Object;
  498. VECTOR Vector;
  499. TRANSFORM *Trans;
  500. {
  501.   Transform_Fractal(Object, Trans);
  502. }
  503.  
  504. /*****************************************************************************
  505. *
  506. * FUNCTION
  507. *
  508. * INPUT
  509. *   
  510. * OUTPUT
  511. *   
  512. * RETURNS
  513. *   
  514. * AUTHOR
  515. *
  516. *   Pascal Massimino
  517. *   
  518. * DESCRIPTION
  519. *
  520. *   -
  521. *
  522. * CHANGES
  523. *
  524. *   Dec 1994 : Creation.
  525. *
  526. ******************************************************************************/
  527.  
  528. static void Scale_Fractal(Object, Vector, Trans)
  529. OBJECT *Object;
  530. VECTOR Vector;
  531. TRANSFORM *Trans;
  532. {
  533.   Transform_Fractal(Object, Trans);
  534. }
  535.  
  536. /*****************************************************************************
  537. *
  538. * FUNCTION
  539. *
  540. * INPUT
  541. *
  542. * OUTPUT
  543. *
  544. * RETURNS
  545. *
  546. * AUTHOR
  547. *
  548. *   Pascal Massimino
  549. *
  550. * DESCRIPTION
  551. *
  552. *   -
  553. *
  554. * CHANGES
  555. *
  556. *   Dec 1994 : Creation.
  557. *   Mar 1996 : Moved call to Recompute_BBox to Compute_Fractal_BBox() (TW)
  558. *
  559. ******************************************************************************/
  560.  
  561. static void Transform_Fractal(Object, Trans)
  562. OBJECT *Object;
  563. TRANSFORM *Trans;
  564. {
  565.   FRACTAL *Fractal = (FRACTAL *) Object;
  566.  
  567.   if (((FRACTAL *) Object)->Trans == NULL)
  568.   {
  569.     ((FRACTAL *) Object)->Trans = Create_Transform();
  570.   }
  571.  
  572.   Compose_Transforms(Fractal->Trans, Trans);
  573.  
  574.   Compute_Fractal_BBox((FRACTAL *) Object);
  575. }
  576.  
  577. /*****************************************************************************
  578. *
  579. * FUNCTION
  580. *
  581. * INPUT
  582. *   
  583. * OUTPUT
  584. *   
  585. * RETURNS
  586. *   
  587. * AUTHOR
  588. *
  589. *   Pascal Massimino
  590. *   
  591. * DESCRIPTION
  592. *
  593. *   -
  594. *
  595. * CHANGES
  596. *
  597. *   Dec 1994 : Creation.
  598. *
  599. ******************************************************************************/
  600.  
  601. static void Invert_Fractal(Object)
  602. OBJECT *Object;
  603. {
  604.   ((FRACTAL *) Object)->Inverted ^= TRUE;
  605. }
  606.  
  607. /*****************************************************************************
  608. *
  609. * FUNCTION
  610. *
  611. * INPUT
  612. *   
  613. * OUTPUT
  614. *   
  615. * RETURNS
  616. *   
  617. * AUTHOR
  618. *
  619. *   Pascal Massimino
  620. *   
  621. * DESCRIPTION
  622. *
  623. *   -
  624. *
  625. * CHANGES
  626. *
  627. *   Dec 1994 : Creation.
  628. *   Mar 1996 : Added call to recompute_BBox() to bottom (TW)
  629. *
  630. ******************************************************************************/
  631.  
  632. static void Compute_Fractal_BBox(Fractal)
  633. FRACTAL *Fractal;
  634. {
  635.   DBL R;
  636.  
  637.   switch (Fractal->Algebra)
  638.   {
  639.     case QUATERNION_TYPE:
  640.  
  641.       R = 1.0 + sqrt(Sqr(Fractal->Julia_Parm[X]) + Sqr(Fractal->Julia_Parm[Y]) + Sqr(Fractal->Julia_Parm[Z]) + Sqr(Fractal->Julia_Parm[T]));
  642.       R += Fractal_Tolerance; /* fix bug when Julia_Parameter exactly 0 */
  643.  
  644.       if (R > 2.0)
  645.       {
  646.         R = 2.0;
  647.       }
  648.  
  649.       Fractal->Exit_Value = Sqr(R);
  650.  
  651.       break;
  652.  
  653.     case HYPERCOMPLEX_TYPE:
  654.     default:
  655.  
  656.       R = 4.0;
  657.  
  658.       Fractal->Exit_Value = 16.0;
  659.  
  660.       break;
  661.   }
  662.  
  663.   Fractal->Radius_Squared = Sqr(R);
  664.  
  665.   Fractal->Inverted = FALSE;
  666.  
  667.   Make_BBox(Fractal->BBox, -R, -R, -R, 2.0 * R, 2.0 * R, 2.0 * R);
  668.  
  669.   Recompute_BBox(&Fractal->BBox, Fractal->Trans);
  670. }
  671.  
  672. /*****************************************************************************
  673. *
  674. * FUNCTION
  675. *
  676. * INPUT
  677. *   
  678. * OUTPUT
  679. *
  680. * RETURNS
  681. *
  682. * AUTHOR
  683. *
  684. *   Pascal Massimino
  685. *
  686. * DESCRIPTION
  687. *
  688. *   -
  689. *
  690. * CHANGES
  691. *
  692. *   Dec 1994 : Creation.
  693. *
  694. ******************************************************************************/
  695.  
  696. FRACTAL *Create_Fractal()
  697. {
  698.   FRACTAL *New;
  699.  
  700.   New = (FRACTAL *) POV_MALLOC(sizeof(FRACTAL), "Fractal Set");
  701.  
  702.   INIT_OBJECT_FIELDS(New, BASIC_OBJECT, &Fractal_Methods)
  703.  
  704.   New->Trans = NULL;
  705.  
  706.   Make_Vector(New->Center, 0.0, 0.0, 0.0);
  707.  
  708.   New->Julia_Parm[X] = 1.0;
  709.   New->Julia_Parm[Y] = 0.0;
  710.   New->Julia_Parm[Z] = 0.0;
  711.   New->Julia_Parm[T] = 0.0;
  712.  
  713.   New->Slice[X] = 0.0;
  714.   New->Slice[Y] = 0.0;
  715.   New->Slice[Z] = 0.0;
  716.   New->Slice[T] = 1.0;
  717.   New->SliceDist = 0.0;
  718.  
  719.   New->Exit_Value = 4.0;
  720.  
  721.   New->n = 20;
  722.  
  723.   New->Precision = 1.0 / 20.0;
  724.  
  725.   New->Inverted = FALSE;
  726.  
  727.   New->Algebra = QUATERNION_TYPE;
  728.  
  729.   New->Sub_Type = SQR_STYPE;
  730.  
  731.   New->Bound = NULL;
  732.  
  733.   New->Clip = NULL;
  734.  
  735.   New->Normal_Calc_Method = NULL;
  736.   New->Iteration_Method   = NULL;
  737.   New->D_Iteration_Method = NULL;
  738.   New->F_Bound_Method     = NULL;
  739.   New->Complex_Function_Method = NULL;
  740.  
  741.   New->Radius_Squared = 0.0;
  742.   New->exponent.x = 0.0;
  743.   New->exponent.y = 0.0;
  744.   
  745.   return (New);
  746. }
  747.  
  748. /*****************************************************************************
  749. *
  750. * FUNCTION
  751. *
  752. * INPUT
  753. *   
  754. * OUTPUT
  755. *   
  756. * RETURNS
  757. *   
  758. * AUTHOR
  759. *
  760. *   Pascal Massimino
  761. *   
  762. * DESCRIPTION
  763. *
  764. *   -
  765. *
  766. * CHANGES
  767. *
  768. *   Dec 1994 : Creation.
  769. *
  770. ******************************************************************************/
  771.  
  772. static void *Copy_Fractal(Object)
  773. OBJECT *Object;
  774. {
  775.   FRACTAL *New;
  776.  
  777.   New = Create_Fractal();
  778.  
  779.   *New = *((FRACTAL *) Object);
  780.  
  781.   New->Trans = Copy_Transform(((FRACTAL *) Object)->Trans);
  782.  
  783.   return (New);
  784. }
  785.  
  786. /*****************************************************************************
  787. *
  788. * FUNCTION
  789. *
  790. * INPUT
  791. *   
  792. * OUTPUT
  793. *   
  794. * RETURNS
  795. *   
  796. * AUTHOR
  797. *
  798. *   Pascal Massimino
  799. *   
  800. * DESCRIPTION
  801. *
  802. *   -
  803. *
  804. * CHANGES
  805. *
  806. *   Dec 1994 : Creation.
  807. *
  808. ******************************************************************************/
  809.  
  810. static void Destroy_Fractal(Object)
  811. OBJECT *Object;
  812. {
  813.   Destroy_Transform(((FRACTAL *) Object)->Trans);
  814.   POV_FREE(Object);
  815. }
  816.  
  817. /*****************************************************************************
  818. *
  819. * FUNCTION
  820. *
  821. * INPUT
  822. *   
  823. * OUTPUT
  824. *   
  825. * RETURNS
  826. *   
  827. * AUTHOR
  828. *
  829. *   Pascal Massimino
  830. *   
  831. * DESCRIPTION
  832. *
  833. *   -
  834. *
  835. * CHANGES
  836. *
  837. *   Dec 1994 : Creation.
  838. *
  839. ******************************************************************************/
  840.  
  841. void SetUp_Fractal(Fractal)
  842. FRACTAL *Fractal;
  843. {
  844.   switch (Fractal->Algebra)
  845.   {
  846.     case QUATERNION_TYPE:
  847.  
  848.       switch(Fractal->Sub_Type)
  849.       {
  850.         case CUBE_STYPE:
  851.           Fractal->Iteration_Method = Iteration_z3;
  852.           Fractal->Normal_Calc_Method = Normal_Calc_z3;
  853.           Fractal->D_Iteration_Method = D_Iteration_z3;
  854.           break;
  855.         case SQR_STYPE:
  856.           Fractal->Iteration_Method = Iteration_Julia;
  857.           Fractal->D_Iteration_Method = D_Iteration_Julia;
  858.           Fractal->Normal_Calc_Method = Normal_Calc_Julia;
  859.           break;
  860.         default:
  861.           Error("illegal function: quaternion only supports sqr and cube");
  862.       }
  863.       Fractal->F_Bound_Method = F_Bound_Julia;
  864.  
  865.       break;
  866.  
  867.     case HYPERCOMPLEX_TYPE:
  868.  
  869.       switch (Fractal->Sub_Type)
  870.       {
  871.         case RECIPROCAL_STYPE:
  872.  
  873.           Fractal->Iteration_Method = Iteration_HCompl_Reciprocal;
  874.           Fractal->Normal_Calc_Method = Normal_Calc_HCompl_Reciprocal;
  875.           Fractal->D_Iteration_Method = D_Iteration_HCompl_Reciprocal;
  876.           Fractal->F_Bound_Method = F_Bound_HCompl_Reciprocal;
  877.  
  878.           break;
  879.  
  880.         case EXP_STYPE: 
  881.         case LOG_STYPE: 
  882.         case SIN_STYPE: 
  883.         case ASIN_STYPE:
  884.         case COS_STYPE: 
  885.         case ACOS_STYPE:
  886.         case TAN_STYPE: 
  887.         case ATAN_STYPE:
  888.         case SINH_STYPE:
  889.         case ASINH_STYPE:
  890.         case COSH_STYPE:
  891.         case ACOSH_STYPE:
  892.         case TANH_STYPE:
  893.         case ATANH_STYPE:
  894.         case PWR_STYPE: 
  895.  
  896.           Fractal->Iteration_Method = Iteration_HCompl_Func;
  897.           Fractal->Normal_Calc_Method = Normal_Calc_HCompl_Func;
  898.           Fractal->D_Iteration_Method = D_Iteration_HCompl_Func;
  899.           Fractal->F_Bound_Method = F_Bound_HCompl_Func;
  900.           Fractal->Complex_Function_Method = Complex_Function_List[Fractal->Sub_Type];
  901.  
  902.           break;
  903.  
  904.         case CUBE_STYPE:
  905.  
  906.           Fractal->Iteration_Method = Iteration_HCompl_z3;
  907.           Fractal->Normal_Calc_Method = Normal_Calc_HCompl_z3;
  908.           Fractal->D_Iteration_Method = D_Iteration_HCompl_z3;
  909.           Fractal->F_Bound_Method = F_Bound_HCompl_z3;
  910.  
  911.           break;
  912.  
  913.         default:  /* SQR_STYPE or else... */
  914.  
  915.           Fractal->Iteration_Method = Iteration_HCompl;
  916.           Fractal->Normal_Calc_Method = Normal_Calc_HCompl;
  917.           Fractal->D_Iteration_Method = D_Iteration_HCompl;
  918.           Fractal->F_Bound_Method = F_Bound_HCompl;
  919.  
  920.           break;
  921.       }
  922.  
  923.       break;
  924.  
  925.     default:
  926.  
  927.       Error("Algebra unknown in fractal.");
  928.   }
  929.  
  930.   Allocate_Iteration_Stack(Fractal->n);
  931.  
  932.   Compute_Fractal_BBox(Fractal);
  933. }
  934.  
  935. /*****************************************************************************
  936. *
  937. * FUNCTION
  938. *
  939. * INPUT
  940. *
  941. * OUTPUT
  942. *
  943. * RETURNS
  944. *
  945. * AUTHOR
  946. *
  947. *   Pascal Massimino
  948. *
  949. * DESCRIPTION
  950. *
  951. *   -
  952. *
  953. * CHANGES
  954. *
  955. *   Dec 1994 : Creation.
  956. *
  957. ******************************************************************************/
  958.  
  959. void Allocate_Iteration_Stack(n)
  960. int n;
  961. {
  962.   if (n > Allocated_Iteration_Stack_Length)
  963.   {
  964.     Sx = (DBL *) POV_REALLOC(Sx, (n + 1) * sizeof(DBL), "x iteration stack");
  965.     Sy = (DBL *) POV_REALLOC(Sy, (n + 1) * sizeof(DBL), "y iteration stack");
  966.     Sz = (DBL *) POV_REALLOC(Sz, (n + 1) * sizeof(DBL), "w iteration stack");
  967.     Sw = (DBL *) POV_REALLOC(Sw, (n + 1) * sizeof(DBL), "z iteration stack");
  968.  
  969.     Allocated_Iteration_Stack_Length = n;
  970.   }
  971. }
  972.  
  973. /*****************************************************************************
  974. *
  975. * FUNCTION
  976. *
  977. * INPUT
  978. *   
  979. * OUTPUT
  980. *   
  981. * RETURNS
  982. *   
  983. * AUTHOR
  984. *
  985. *   Pascal Massimino
  986. *   
  987. * DESCRIPTION
  988. *
  989. *   -
  990. *
  991. * CHANGES
  992. *
  993. *   Dec 1994 : Creation.
  994. *
  995. ******************************************************************************/
  996.  
  997. void Free_Iteration_Stack()
  998. {
  999.   if (Sx != NULL)
  1000.   {
  1001.     POV_FREE(Sx);
  1002.     POV_FREE(Sy);
  1003.     POV_FREE(Sz);
  1004.     POV_FREE(Sw);
  1005.   }
  1006.  
  1007.   Sx = NULL;
  1008.   Sy = NULL;
  1009.   Sz = NULL;
  1010.   Sw = NULL;
  1011.  
  1012.   Allocated_Iteration_Stack_Length = 0;
  1013. }
  1014.  
  1015.   
  1016.